{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "03f823e3-6d32-4ef6-8558-d34e6c20900d",
   "metadata": {},
   "source": [
    "## Multiple Chain 快速入门\n",
    "\n",
    "Runnables 可以轻松地用来串联多个 Chains，使用 RunnablePassthrough 将输出同时传给多条后继链。\n",
    "\n",
    "```\n",
    "     Input\n",
    "      / \\\n",
    "     /   \\\n",
    " Chain1 Chain2\n",
    "     \\   /\n",
    "      \\ /\n",
    "      Combine\n",
    "```\n",
    "\n",
    "本指南展示如何使用 Runnable 实现多个 AI 关于相同话题的辩论：\n",
    "\n",
    "```\n",
    "    输入话题\n",
    "       |\n",
    "       |\n",
    "    原始观点\n",
    "      / |\\\n",
    "     /  |  \\\n",
    " 正面论述| 反面论述\n",
    "     \\  | /\n",
    "      \\ |/\n",
    "     最终总结\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "3a699e45-c4ea-460a-8dec-1ab973b5daf7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入相关模块，包括运算符、输出解析器、聊天模板、ChatOpenAI 和 运行器\n",
    "from operator import itemgetter\n",
    "from langchain_core.output_parsers import StrOutputParser\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.runnables import RunnablePassthrough\n",
    "\n",
    "# 创建一个计划器，生成一个关于给定输入的论证\n",
    "planner = (\n",
    "    ChatPromptTemplate.from_template(\"生成关于以下内容的论点: {input}\")\n",
    "    | ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "    | StrOutputParser()\n",
    "    | {\"base_response\": RunnablePassthrough()}\n",
    ")\n",
    "\n",
    "# 创建正面论证的处理链，列出关于基础回应的正面或有利的方面\n",
    "arguments_for = (\n",
    "    ChatPromptTemplate.from_template(\n",
    "        \"列出关于{base_response}的正面或有利的方面\"\n",
    "    )\n",
    "    | ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "    | StrOutputParser()\n",
    ")\n",
    "\n",
    "# 创建反面论证的处理链，列出关于基础回应的反面或不利的方面\n",
    "arguments_against = (\n",
    "    ChatPromptTemplate.from_template(\n",
    "        \"列出关于{base_response}的反面或不利的方面\"\n",
    "    )\n",
    "    | ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "    | StrOutputParser()\n",
    ")\n",
    "\n",
    "# 创建最终响应者，综合原始回应和正反论点生成最终的回应\n",
    "final_responder = (\n",
    "    ChatPromptTemplate.from_messages(\n",
    "        [\n",
    "            (\"ai\", \"{original_response}\"),\n",
    "            (\"human\", \"正面观点:\\n{results_1}\\n\\n反面观点:\\n{results_2}\"),\n",
    "            (\"system\", \"给出批评后生成最终回应\"),\n",
    "        ]\n",
    "    )\n",
    "    | ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "    | StrOutputParser()\n",
    ")\n",
    "\n",
    "# 构建完整的处理链，从生成论点到列出正反论点，再到生成最终回应\n",
    "chain = (\n",
    "    planner\n",
    "    | {\n",
    "        \"results_1\": arguments_for,\n",
    "        \"results_2\": arguments_against,\n",
    "        \"original_response\": itemgetter(\"base_response\"),\n",
    "    }\n",
    "    | final_responder\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "21340302-7a49-48af-a4a5-b516cb5596e0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "在分析房地产市场低迷时，正面和反面的观点都提供了宝贵的视角，但也存在一定的局限性。以下是对上述观点的批评和最终回应：\n",
      "\n",
      "### 批评\n",
      "\n",
      "1. **市场修正与健康发展**：\n",
      "   - **批评**：市场修正可能会导致短期内的经济衰退，影响就业和消费，尤其是对依赖房地产市场的行业如建筑和家居等。\n",
      "   - **回应**：尽管短期内可能面临挑战，但长期来看，健康的市场修正有助于消除不合理的价格水平，为未来的稳定增长奠定基础。\n",
      "\n",
      "2. **购房者机会**：\n",
      "   - **批评**：市场低迷虽然提供了购房者机会，但对于许多家庭来说，依然可能面临高额的贷款利率和不确定的经济环境，从而限制实际购房能力。\n",
      "   - **回应**：虽然购房者面临挑战，但市场的低迷确实提供了机会，尤其是对于首次购房者和那些能够承受更高风险的投资者而言。\n",
      "\n",
      "3. **租赁市场发展**：\n",
      "   - **批评**：租赁市场的繁荣并不一定能替代购房市场的需求，长期依赖租赁可能导致家庭资产的积累减缓。\n",
      "   - **回应**：租赁市场的发展确实满足了灵活性需求，并为投资者提供机会，促进了住宅市场的多样性。\n",
      "\n",
      "4. **推动政策创新**：\n",
      "   - **批评**：政府政策的调整可能面临落实困难，且短期措施未必能根本解决市场低迷的问题。\n",
      "   - **回应**：政策创新虽然面临挑战，但它们为市场注入了活力，并可为长期的经济复苏提供支持。\n",
      "\n",
      "5. **社会结构变化的机遇**：\n",
      "   - **批评**：社会结构的变化可能导致传统住房需求的下降，而开发商未必能迅速适应市场的变化。\n",
      "   - **回应**：尽管存在适应困难，但市场的变化也激励了开发商创新，促使其推出更多符合现代需求的产品。\n",
      "\n",
      "6. **可持续发展意识增强**：\n",
      "   - **批评**：可持续发展虽然重要，但在短期低迷的情况下，开发商和投资者可能更关注成本控制而非长期环保目标。\n",
      "   - **回应**：可持续发展的长远利益仍然是推动行业转型的重要动力，低迷市场反而可能促使更有意识的投资。\n",
      "\n",
      "### 最终回应\n",
      "\n",
      "房地产市场的低迷现象是复杂且多维的，虽然带来了诸多挑战，但也提供了潜在的机遇。市场修正有助于消除泡沫，购房者在低迷时期能够以较低的价格入市，租赁市场的繁荣为不同人群提供了灵活的居住选择。而政策创新、社会结构的变化以及可持续发展意识的增强，都为市场的调整和未来的增长创造了条件。因此，尽管市场低迷有其消极影响，但从长远来看，它可能为房地产市场带来更健康、更可持续的发展方向。\n"
     ]
    }
   ],
   "source": [
    "print(chain.invoke({\"input\": \"房地产低迷\"}))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a9aabaf-2ce7-4ce2-ad44-f11b0dfe0f4b",
   "metadata": {},
   "source": [
    "#### 流式输出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "58380571-fa69-426e-95a8-d17ebd61d147",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "在讨论全球经济的正面和反面观点时，我们可以看到各个方面的复杂性和相互关联性。以下是对以上论点的综合回应：\n",
      "\n",
      "### 综合回应\n",
      "\n",
      "1. **全球化的复杂性**：全球化确实带来了经济增长和文化交流，但也伴随着文化同质化和环境问题。为了实现经济与文化的双赢，各国需要在全球化的过程中，重视保护和弘扬地方文化，同时制定更严格的环境保护政策，以确保可持续发展。\n",
      "\n",
      "2. **科技进步与包容性**：科技的进步是推动生产力提升的重要因素，但数字鸿沟和就业不稳定是不可忽视的挑战。各国应加强教育和技能培训，确保所有人都能平等地享受到科技进步的红利，从而减少社会不平等和不安定性。\n",
      "\n",
      "3. **可持续发展的双重目标**：在追求经济增长的同时，必须重视环境保护。各国应采取更有效的环境政策，平衡经济发展与生态保护，避免资源争夺引发的地缘政治紧张。\n",
      "\n",
      "4. **货币政策的审慎管理**：货币政策在促进经济增长方面发挥了重要作用，但也带来了金融不稳定和不平等加剧的问题。各国央行需要在刺激经济和控制风险之间找到平衡，确保货币政策的可持续性。\n",
      "\n",
      "5. **新兴市场的机遇与挑战**：新兴市场的崛起为全球经济注入活力，但也带来了对传统经济体的依赖风险。发达国家应与新兴市场建立更紧密的合作关系，以应对全球经济波动带来的挑战。\n",
      "\n",
      "6. **贸易政策的协调**：保护主义政策虽然短期内可能保护某些行业，但长期来看会损害全球经济的整体发展。各国应积极推动自由贸易，促进国际合作，以实现共同繁荣。\n",
      "\n",
      "7. **疫情后的复苏策略**：疫情后的经济复苏确实存在不平衡的问题，各国应采取灵活的财政政策，优先支持受影响严重的行业和地区，确保经济复苏的包容性和可持续性。\n",
      "\n",
      "### 结论\n",
      "\n",
      "全球经济是一个复杂的系统，各国在追求自身利益的同时，必须加强合作与协调，以应对共同面临的挑战。通过创新、教育和可持续发展，世界各国可以在经济增长的基础上，推动更公平和包容的全球经济体系。关键在于各国如何在面对机遇与挑战时，采取适当的政策和措施，以实现长远的可持续发展。"
     ]
    }
   ],
   "source": [
    "## chain 最终输出经过了 StrOutputParser 处理，所以可以直接输出流式输出 s\n",
    "for s in chain.stream({\"input\": \"全球经济\"}):\n",
    "    print(s, end=\"\", flush=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f5ace837-8c01-4661-832e-d0b7ec4e20c6",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "157236cc-1acd-4c2a-ade8-509d252f9941",
   "metadata": {},
   "source": [
    "### Homework: 实现一个多链版本的代码生成，输入功能需求，输出2种（Python，Java）以上编程语言的代码实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8b540134-3e4c-409d-b801-f861bfa184c0",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
